/**
 * Converter.java
 */
package agngui.tools;
import agngui.ui.*;

import java.util.Map;
import java.util.HashMap;

/**
 * This class converts units according to type!
 * 
 * @author Ben Bloom
 * @author Phil Johnson
 */
public class Converter {
	
	/**
	 * the mapping from a unit type to the default type of the given unit
	 */
    private static Map< String, Double > conversionFactors = new HashMap<String, Double>();

    static {
        /* Distance (m) */
        conversionFactors.put( "nm" , 1e-9         );
        conversionFactors.put( "cm" , 1e-2         );
        conversionFactors.put( "m"  , 1.0           );
        conversionFactors.put( "km" , 1e3          );
        conversionFactors.put( "pc" , 3.08568025e16 );
        conversionFactors.put( "kpc", 3.08568025e19 );
        conversionFactors.put( "Mpc", 3.08568025e22 );
        conversionFactors.put( "ly" , 9.4605284e15  );
        conversionFactors.put( "AU" , 149598e6      );
        conversionFactors.put( "a0" , 1e-10         );

        /* Angle (deg) */
        conversionFactors.put( "deg",   1.0        );
        conversionFactors.put( "rad",   57.2957795 );
        conversionFactors.put( "arcsec",(1/3600.0) );
        
        /* Mass (kg)*/
        conversionFactors.put( "amu", 1.66053886e-27 );
        conversionFactors.put( "g"  , 1e-3           );
        conversionFactors.put( "kg" , 1.0            );
        conversionFactors.put( "SM" , 1.98892e30     ); 

        /* Time (s) */
        conversionFactors.put( "ms"  , 1e-3            );
        conversionFactors.put( "s"   , 1.0             );
        conversionFactors.put( "min" , 60.0            );
        conversionFactors.put( "hour", 60.0 * 60       );
        conversionFactors.put( "day" , 60 * 60 * 24.0  );
        conversionFactors.put( "year", 60 * 60 * 24 * 365.25 );
        
        /* Velocity (c) */
        conversionFactors.put( "m/s", 1.0/3.0e8 );
        conversionFactors.put( "c"  , 1.0 );

        /* Number density 1/(m^3) */
        conversionFactors.put( "m^-3" , 1.0 );
        conversionFactors.put( "cm^-3", 1e3 ); 
    };
    
    /**
     * hidden constructor, making this a singleton
     */
    private Converter() {
    	
    }

    /**
     * convertUnits
     *
     * Converts value of a certain unit type to another unit denomination. src and
     * dest must be the same unit type.
     *  
     * @param value The value of the unit type specified by src
     * @param src   The source unit type 
     * @param dest  The destination unit type
     * @return the converted value if arguments are valid, and the unconverted value
     *         otherwise.
     */
    public static double convertUnits( double value, String src, String dest ) {
        if( Field.getType( src ) != Field.getType( dest ) ) {
            throw new IllegalArgumentException( "source and destination units in convertUnits do not match" );
        }

        if( Field.getType( src ) == UNIT_TYPE.NONE ) return value;

        return value * (conversionFactors.get( src ) / conversionFactors.get( dest ));
    }
}
